#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,2004 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)27   1.47   src/csm/core/cmds/rmnode.perl, csmcore, csm_rameh, rameh0431a 10/4/03 14:16:09

use strict;
use locale;
BEGIN
  {
	# this enables us to redirect where it looks for other CSM files during development
	$::csmroot = $ENV{'CSM_ROOT'} ? $ENV{'CSM_ROOT'} : '/opt/csm';
	$::csmpm = "$::csmroot/pm";
	$::csmbin = "$::csmroot/bin";
  }
use lib $::csmpm;
use Getopt::Std;
use NodeUtils;
use CSMDefs;
use InstallUtils;
use InstallKRB5Utils;

# get the global definitions we need for this command
#    in this case get_OSDefs uses the attrs of the management
#    server to identify the correct definitions
%::myOSDefs= InstallUtils->get_OSDefs();

# For the usage, see nodecmds.msg
sub usage { NodeUtils->message('I', 'IMsgRmnodeUsage');  exit (scalar(@_) ? $_[0] : 1); }

$ENV{'CT_MANAGEMENT_SCOPE'} = 1;           # set local scope because we only want classes on the mgmt svr
$::MSGSET = 'rmnode';     # setting this explicitly 
$::MSGCAT = 'nodecmds.cat';
$::MSGMAPPATH = "$::csmroot/msgmaps";

# Parse the cmd line args and check them
if (! getopts('uhvVN:f:n:') ) { &usage; }
if ($::opt_h) { &usage(0); }
if (scalar(@ARGV)<1 && !defined($::opt_N) && !defined($::opt_f) && !defined($::opt_n)) { &usage; }

$::VERBOSE = $::opt_v || $::opt_V;
$::RMNODE_CLIENT = "/opt/csm/csmbin/rmnode_client";

$::exported=0;


#
# Get KRB5 credentials
#
my $krb5_tgt =0;
my $KRB5CCNAME="";
$KRB5CCNAME=InstallKRB5Utils->getKRB5tgt;
if ($KRB5CCNAME ne "") {
	$ENV{'KRB5CCNAME'} = $KRB5CCNAME;
	$krb5_tgt=1;
}


my $nodelist = NodeUtils->gatherNodeList(\@ARGV);
if (!scalar(@$nodelist)) { $::MSGSET='createnode'; NodeUtils->message('E13','EMsgNO_NODES'); }
my $res2unres;
($nodelist, $res2unres) = NodeUtils->resolveAndUndup($nodelist);
my $where = NodeUtils->buildWhereInList($nodelist);

if ($::opt_u)
{

  #Make a Hash of ManagedNodes as keys with their Managemnent Sever as the value
  %::MgNodeMgSvrHash;
  %::MgNodeMgOSnameHash;
  @::My_Node_list;
  my ($mynode_file, $myhostname, $mymanagemnentserver, @myNodeList, $myDshCmd, $myNodeOSName, $mymode, @localresults);
  my ($myval, $myval1, $myval2);
  @myNodeList=@$nodelist;
  my $myresults=NodeUtils->listNodeAttrs(\@myNodeList,"Hostname, ManagementServer, Mode, InstallOSName");
  foreach $myval (@$myresults)
  {
    ($myhostname, $mymanagemnentserver, $mymode, $myNodeOSName)=split(':\|:',$myval);
    if (!($mymode=~ /PreManaged/) and !($mymode =~ /$::CSMLITE/))
    {
      $::MgNodeMgSvrHash{"$myhostname"}=$mymanagemnentserver;
      $::MgNodeMgOSnameHash{"$myhostname"}=$myNodeOSName;  
      push (@::My_Node_list,$myhostname);
    }
  }

  if (scalar(keys %::MgNodeMgSvrHash) !=0)
  { 
    #Run dsh command on all the nodes to get the Management Server fromn the node
    $mynode_file = InstallUtils->make_node_list_file(\@::My_Node_list); #put all dest nodes in tmp file
    $ENV{'DSH_LIST'} = $mynode_file;
    #$myDshCmd="$::DSH $::MGMTSVR";
    #$myDshCmd="$::DSH \" CT_MANAGEMENT_SCOPE=1 lsrsrc-api -s IBM.ManagementServer::\\\"ManagerType='CSM'\\\"::Hostname\"";
    $myDshCmd="$::DSH -v  \" lsrsrc-api -s IBM.ManagementServer::\\\"ManagerType='CSM'\\\"::Hostname\"";
    NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','V', 'IMsgRUN_CMD',$myDshCmd);
    @localresults=`$myDshCmd`;
    if ($? != 0)
    {
      NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','E', 'EMsgNO_DSH');
      `$::RM -rf $mynode_file`;
    }
    $myval="";
    # For each ManagedNode compare the Management server value with value from the dsh command
    # if not equal the delete the node
    foreach my $myval (@localresults)
    {
        chomp $myval;
        ($myval1, $myval2)=split(': ',$myval);
        if ($::MgNodeMgSvrHash{"$myval1"} ne $myval2)
        {
            delete $::MgNodeMgSvrHash{"$myval1"};
            delete $::MgNodeMgOSnameHash{"$myval1"};
        }
    }
    InstallUtils->close_delete_file($::NODE_LIST_FILE, $mynode_file); #delete node file 
  }

}

# Delete the nodes
my $outref = NodeUtils->runrmccmd('rmrsrc-api', '-i', qq(-s IBM.ManagedNode::$where));
my $numfound = scalar(@$outref);
my $numtofind = (defined($nodelist) ? scalar(@$nodelist) : 0);

# Check for nodes not found so we can try the unresolved names
if ($numtofind && $numfound<$numtofind)
  {
	# If we only try the names that were resolved into a different name, then we should not end
	# up trying to remove any nodes twice.
	my @a;
	foreach my $k (keys %$res2unres) { if ($k ne "" && $k ne $$res2unres{$k}) { push @a, @{$$res2unres{$k}}; } }
	$where = NodeUtils->buildWhereInList(\@a);
	$outref = NodeUtils->runrmccmd('rmrsrc-api', '-i', qq(-s IBM.ManagedNode::$where));
    $numfound += scalar(@$outref);
  }

if ($numfound < $numtofind)
  {
	$::MSGSET = 'lsnode';
	if (scalar(@$nodelist) == 1) { NodeUtils->message('E12', 'EMsgNODE_NOT_FOUND', $$nodelist[0]); }
	elsif (scalar(@$nodelist) <= 10) { NodeUtils->message('W12', 'EMsgSOME_NOT_FOUND_LIST', join(', ',@$nodelist)); }
	else { NodeUtils->message('W12', 'EMsgSOME_NOT_FOUND'); }
  }

#if the -u option is set then run rmnode.client on the node which in turn
#uninstalls csm, rsct packages and logs for Linux and log files for AIX on the 
#node after removing the node from the database
if ($::opt_u)
{

  if ($::PLTFRM eq "AIX") {
    #  Ensure the binaries in /csminstall/csm are current
    InstallUtils->copyBinaries;
  }

  # use dsh run /opt/csm/csmbin/rmnode.client
  # and unmount
  if(scalar @::My_Node_list){
	  &moveRmnode_client(\@::My_Node_list);
  	if(&run_DSH_Commands(\@::My_Node_list) != 0)
  	{
  	   # An error occured when executing DSH
  	   NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','E2', 'EMsgNO_DSH');
  	}
}

  if ($::exported)
  {
    InstallUtils->unexport_csminstall('/csminstall/csm');
  }

  #NodeUtils->message('I','IMsgDidnotRemoveDir',join(', ',@::csmUninstallList_Directories));
  #NodeUtils->message('I','IMsgDidnotRemovePkgs',join(', ',@::csmUninstallList_Packages));
  NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','I', 'IMsgDidnotUninstallOpenSrcPkgs');
  NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','I', 'IMsgDidnotUnconfigureRemoteShellNode');

}

# get rid of KRB5 tgt if gotten
if ($krb5_tgt==1) {

   `$::CSMCSMBIN/k5destroytgt 2>&1`;  # never errors
}

exit;
#--------------------------------------------------------
#
# Sub routines
#
#--------------------------------------------------------
sub run_DSH_Commands
{
    my ($nodelist) = @_;
    my @dsh_results;
    my $rc = 0;
    my $rmnode_client_cmd=$::RMNODE_CLIENT;
    if ($::VERBOSE)
    {
	$rmnode_client_cmd .= " -v";
    }
    my $node_file = InstallUtils->make_node_list_file($nodelist); #put all dest nodes in tmp file
    $ENV{'DSH_LIST'} = $node_file;
    my @local_dsh_results=();
    my $dsh_command="$::DSH -v  ";
    $dsh_command .= "$rmnode_client_cmd 2>&1; ";
    NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','V', 'IMsgRUN_CMD',$dsh_command);
    @local_dsh_results = `$dsh_command`;
    $rc = $? ;
    if ($rc != 0)
    {
        # Error executing DSH.
        NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','E', 'EMsgNO_DSH');
    }
    chop @local_dsh_results;
    InstallUtils->close_delete_file($::NODE_LIST_FILE, $node_file); #delete node file
    #push @dsh_results, @local_dsh_results;
    # print errors
    foreach my $line (@local_dsh_results)
    {
        # print "$line\n";
        NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','I', 'IMsgShow_Output',$line);
    }
    return $rc;
}

sub moveRmnode_client{
    my ($nodelist) = @_;
    #first determine which machines do not have /opt/csm/csmbin/rmnode_client
    my $node_file = InstallUtils->make_node_list_file($nodelist); #put all dest nodes in tmp file
    $ENV{'DSH_LIST'} = $node_file;
    my @local_dsh_results=();
    my $dsh_command="LANG=C $::DSH -v  ";
    $dsh_command .= "$::LS $::RMNODE_CLIENT 2>&1; ";
    NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','V', 'IMsgRUN_CMD',$dsh_command);
    @local_dsh_results = `$dsh_command`;
    my @copy_nodes;
    foreach my $line (@local_dsh_results){
	chomp $line;
	my ($node, $info) = split ':', $line, 2;
	if($info =~ m/No such file or directory/){
	    push @copy_nodes, $node;
	}
    }
    if(scalar @copy_nodes){
	# make sure NFS is functioning
	if(InstallUtils->start_nfs != 0)
	{
	    # Could not start NFS.
	    NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','E1', 'EMsgNO_NFS');
	}
	
	# export /csminstall/csm so it can be mounted on the node
	if(InstallUtils->export_csminstall('/csminstall/csm') != 0)
	{
	    # Could not export /csminstall/csm.
	    NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','E1', 'EMsgNO_EXPORT');
	}
	else
	{
	    $::exported++;
	}
	my %MS_HASH = ();		
	foreach my $node(@copy_nodes){
	    my $ms = $::MgNodeMgSvrHash{$node};
	    my $os = $::MgNodeMgOSnameHash{$node};
	    push @{$MS_HASH{$ms}{$os}}, $node;
	}
	foreach my $ms (keys %MS_HASH){
	    foreach my $os (keys %{$MS_HASH{$ms}}){
		my @nodes = @{$MS_HASH{$ms}{$os}};
		if($os eq "Linux"){
		my %lnxOSDefs= InstallUtils->get_OSDefs('Linux','','','','',1);
		    my $node_file = InstallUtils->make_node_list_file(\@nodes); #put all dest nodes in tmp file
		    $ENV{'DSH_LIST'} = $node_file;
		    my @local_dsh_results=();
		    my $dsh_command="$::DSH -v  ";
		    $dsh_command .= "\"$::MKDIR -p  $::CSMCLIENTMNTDIR/csm >/dev/null 2>&1; ";
		    $dsh_command .= "$lnxOSDefs{MOUNT} -r $ms:/csminstall/csm $::CSMCLIENTMNTDIR/csm 2>&1; ";
		    $dsh_command .= "$::COPY $::CSMCLIENTMNTDIR/csm/rmnode_client $::RMNODE_CLIENT 2>&1; ";
		    $dsh_command .= "$lnxOSDefs{UNMOUNT} $::CSMCLIENTMNTDIR/csm 2>&1\"";
		    NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','V', 'IMsgRUN_CMD',$dsh_command);
		    @local_dsh_results = `$dsh_command`;
		    my $rc = $? ;
		    if ($rc != 0)
		    {
			NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','E', 'EMsgNO_DSH');
		    }
		    chop @local_dsh_results;
		    InstallUtils->close_delete_file($::NODE_LIST_FILE, $node_file); #delete node file
		    foreach my $line (@local_dsh_results)
		    {
			NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','I', 'IMsgShow_Output',$line);
		    }
		} # end linux node
		elsif($os eq "AIX"){
			  my %aixOSDefs= InstallUtils->get_OSDefs('AIX','','','','',1);
		    my $node_file = InstallUtils->make_node_list_file(\@nodes); #put all dest nodes in tmp file
		    $ENV{'DSH_LIST'} = $node_file;
		    my @local_dsh_results=();
		    my $dsh_command="$::DSH -v  ";
		    $dsh_command .= "\"$::MKDIR -p  $::CSMCLIENTMNTDIR/csm >/dev/null 2>&1; ";
		    $dsh_command .= "$aixOSDefs{MOUNT} -r $ms:/csminstall/csm $::CSMCLIENTMNTDIR/csm 2>&1; ";
		    $dsh_command .= "$::COPY $::CSMCLIENTMNTDIR/csm/rmnode_client $::RMNODE_CLIENT  2>&1; ";
		    $dsh_command .= "$aixOSDefs{UNMOUNT} $::CSMCLIENTMNTDIR/csm 2>&1\"";
		    NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','V', 'IMsgRUN_CMD',$dsh_command);
		    @local_dsh_results = `$dsh_command`;
		    my $rc = $? ;
		    if ($rc != 0)
		    {
			NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','E', 'EMsgNO_DSH');
		    }
		    chop @local_dsh_results;
		    InstallUtils->close_delete_file($::NODE_LIST_FILE, $node_file); #delete node file
		    foreach my $line (@local_dsh_results)
		    {
			NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','I', 'IMsgShow_Output',$line);
		    }
		} # end aix node
		else{
		    my $string = join ",", @nodes;
		    NodeUtils->messageFromCat('csmInstall.cat',$::MSGMAPPATH,'csminstall','E', 'EMsgUnsupportedOS', $string,$os);
		}
	    }
	}
    }
}
